package top.codetheory.thread._004_ReentrantLock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author:
 * @since: 2024/5/1 上午8:16
 **/
@Slf4j
public class _001_打断 {
    public static void main(String[] args) {
//        test1();
//        test2();
        test3();
    }

    /**
     * ReentrantLock 可打断的方法 lockInterruptibly(); <br>
     * 从结果可以看到，执行打断后，打断状态清除了，变为了false <br>
     * <img src="https://gitee.com/codetheory/img-on1/raw/master/img01/1714522882876-2024-5-108:21:23.png"  />
     */
    public static void test1() {
        ReentrantLock lock = new ReentrantLock();

        Thread t1 = new Thread(() -> {

            try {
                lock.lockInterruptibly();
            } catch (InterruptedException e) {
                e.printStackTrace();
                log.info("打断状态: {}", Thread.currentThread().isInterrupted());
            }
            log.info("被打断后，继续执行后面的代码");
        }, "t1");

        lock.lock();
        t1.start();

        t1.interrupt();

        log.info("main end");
    }

    /**
     * ReentrantLock 不可打断的方法 lock(); <br>
     * 从结果我们可以看到， 即使调用了打断的方法， 并且打断标记已经为true了， 但是t1现在还是在等待锁的状态， 说明lock方法是不可打断的 <br>
     * 在调用unlock之后， t1才会继续执行 <br>
     * <img src="https://gitee.com/codetheory/img-on1/raw/master/img01/1714523357727-2024-5-108:29:18.png"  />
     */
    public static void test2() {
        ReentrantLock lock = new ReentrantLock();

        Thread t1 = new Thread(() -> {
            lock.lock();
            log.info("lock无法被打断，会一直卡在前面一行，等待释放锁");
        }, "t1");

        lock.lock();
        t1.start();

        t1.interrupt();

        log.info("打断状态: {}", t1.isInterrupted());

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        lock.unlock();


        log.info("main end");
    }

    /**
     * 打断synchornized锁 <br>
     * 在主线程中打断t1线程， 但是t1线程是在synchronized锁中， 由于没有获得到锁资源，所以打断是无效的<br>
     * 而上面的使用 ReentrantLock 是可以打断的， 这是因为ReentrantLock是可打断的， 而synchronized是不可打断的 <br>
     * <img src="https://gitee.com/codetheory/img-on1/raw/master/img01/1714672275309-2024-5-301:51:16.png"  />
     */
    public static void test3() {
        Object lock = new Object();

        Thread t1 = new Thread(() -> {
            synchronized (lock) {
                log.info("lock无法被打断，会一直卡在前面一行，等待释放锁");
            }
        }, "t1");

        synchronized (lock) {
            t1.start();
            log.info("打断状态: {}", t1.isInterrupted());
            t1.interrupt();
            log.info("打断状态: {}", t1.isInterrupted());

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }


        log.info("main end");
    }
}